package com.example.system.service.impl;


import com.example.common.constant.SystemConstant;
import com.example.common.utils.ClassUtils;
import com.example.system.domain.Domain;
import com.example.system.domain.bo.PageBo;
import com.example.system.domain.vo.PageVo;
import com.example.system.service.DomainService;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

@Service
public class DomainServiceImpl implements DomainService {

    @Override
    @SneakyThrows
    public PageVo<Domain> getList(PageBo pageBo) {
        String packagePath = SystemConstant.DomainPath;
        // 获取包下所有的类
        List<Class<?>> classes = ClassUtils.getClzFromPkg(packagePath);
//        List<Class<?>> classes = getClasses(packagePath);
        // 遍历类列表，获取每个类的属性
        List<Domain> mapList = new ArrayList<>();
        for (Class<?> clazz : classes) {
            Domain domain = new Domain();
            String domainPath = clazz.getName();
            domain.setDomainPath(domainPath);//类地址
            String[] path = domainPath.split("\\.");
            domain.setDomainName(path[path.length - 1]);//类名称
            Annotation[] classAnnotations = clazz.getDeclaredAnnotations();
            StringBuilder anno = new StringBuilder();//类注解
            for (Annotation annotation : classAnnotations) {
                anno.append(annotation);
            }
            domain.setAnno(anno.toString());
            Field[] fields = clazz.getDeclaredFields();
            List<String> type = new ArrayList<>();
            List<String> name = new ArrayList<>();
            for (Field f : fields) {
                name.add(f.getName());//数据类型
                type.add(f.getType().getName());//数据名称
            }
            domain.setType(type);
            domain.setName(name);
            mapList.add(domain);
        }
        return new PageVo<>(pageBo, mapList);
    }

    // 获取包下所有的类
    private List<Class<?>> getClasses(String packageName) throws ClassNotFoundException, IOException {
        List<Class<?>> classes = new ArrayList<>();
        String packagePath = packageName.replace('.', '/');
        Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources(packagePath);
        List<File> dirs = new ArrayList<>();
        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            dirs.add(new File(resource.getFile()));
        }
        for (File directory : dirs) {
            classes.addAll(findClasses(directory, packageName));
        }
        return classes;
    }

    // 在指定的目录下查找类文件
    private List<Class<?>> findClasses(File directory, String packageName) throws ClassNotFoundException {
        List<Class<?>> classes = new ArrayList<>();
        if (!directory.exists()) {
            return classes;
        }
        File[] files = directory.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                assert !file.getName().contains(".");
                classes.addAll(findClasses(file, packageName + "." + file.getName()));
            } else if (file.getName().endsWith(".class")) {
                Class<?> clazz = Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6));
                classes.add(clazz);
            }
        }
        return classes;
    }
}
